<?php

namespace app\admin\middleware;
use think\facade\Session;
use app\admin\model\AdminUser;
use app\Exception;
use app\service\token\TokenStore;
use app\admin\service\AdminUserManger;
use app\admin\service\RoleManger;
use app\admin\service\RuleGroup;
//use services\login\Token;
use app\admin\service\Token;
class Login
{
    const KEY = "admin_login";
    const OUTTIME = 60*60 *2;
    protected $user = null;

    /**
     * @param \app\Request $req
     * @param \Closure $next
     */
    function handle($req, \Closure $next)
    {
        try{
            $token = $req->cookie('token','');
            $tokeninfo  = $this->getTokenStore()->get($token);
            if (!!$tokeninfo && $tokeninfo['sub'] == 'admin' && $tokeninfo['expire_time'] > time()) {
                $user = app(AdminUserManger::class)->find($tokeninfo['user']['user_id']);
                if(!$user || $user['enable'] == 0){
                    return redirect(admin_url('login'));
                }elseif(!$this->check_auth($user,$req->pathinfo())){
                    return error("无权访问");
                }
                $tokeninfo = $this->getTokenStore()->renew($token,3600);
                $req->setUser(function()use($user){
                    return $user;
                });
                return $next($req);
            }
        }catch(Exception $e){
        }
        return redirect(admin_url('login'));
    }

    function clear()
    {
        Session::delete(self::KEY);
    }

    function check_auth($user,$path)
    {
        $rules = 
        $rules = $user['role']['rules'] ?? [];
        array_push($rules,'my/**');
        /**
         * @var RoleManger $ruleParser
         */
        $ruleParser = app(RoleManger::class);
        foreach($rules as $key=>$v){
            $rules[$key] = $ruleParser->convertRule($v);
        }
        $ruleGroup = new RuleGroup($rules);
        app()->instance('rule',function($path) use($user,$ruleGroup){
            $path = preg_replace(['/^\//','/\.[^\/]+$/'],'',$path);
            if($user['id'] == 1 || $path == '' ||  $path == 'main'){
                return true;
            }
            if($ruleGroup->check($path)){
                return true;
            }else{
                return false;
            }
        });
        return call('rule',[$path]);
    }

    function getUser(){
        return $this->user;
    }

    /**
     * @return Token
     */
    function getTokenStore()
    {
        /** @var Token $tokenStore */
        $tokenStore = app(Token::class);
        return app(Token::class);
    }
}